/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2015-2018. All rights reserved.
 * Description: Signature Verify CBB Library
 * Author: tangzonglei
 * Create: 2015
 * History: 2018/11/23 yebin code rule fixes
 */

#include "../cms/cmscbb_templ.h"
#include "cmscbb_cms_def.h"
#include "../asn1/cmscbb_asn1_decode.h"
#include "../cmscbb_common/cmscbb_def.h"

#if CMSCBB_RELOC_STRICT_CHECK
static CmscbbAsn1Functions g_cvbAsnFuncOct = { CmscbbDecodeOctet, CVB_FALSE };
static CmscbbAsn1Functions g_cvbAsnFuncBits = { CmscbbDecodeBits, CVB_FALSE };
static CmscbbAsn1Functions g_cvbAsnFuncSeq = { CmscbbDecodeSeq, CVB_FALSE };
static CmscbbAsn1Functions g_cvbAsnFuncInt = { CmscbbDecodeInt, CVB_FALSE };
static CmscbbAsn1Functions g_cvbAsnFuncSetOf = { CmscbbDecodeSetof, CVB_FALSE };
static CmscbbAsn1Functions g_cvbAsnFuncMap = { CmscbbDecodeMap, CVB_FALSE };
static CmscbbAsn1Functions g_cvbAsnFuncBitsToInt = { CmscbbBitsToInt, CVB_FALSE };
static CmscbbAsn1Functions g_cvbAsnFuncExku = { CmscbbOidToExku, CVB_FALSE };
#else
static CmscbbAsn1Functions g_cvbAsnFuncOct = { CmscbbDecodeOctet };
static CmscbbAsn1Functions g_cvbAsnFuncBits = { CmscbbDecodeBits };
static CmscbbAsn1Functions g_cvbAsnFuncSeq = { CmscbbDecodeSeq };
static CmscbbAsn1Functions g_cvbAsnFuncInt = { CmscbbDecodeInt };
static CmscbbAsn1Functions g_cvbAsnFuncSetOf = { CmscbbDecodeSetof };
static CmscbbAsn1Functions g_cvbAsnFuncMap = { CmscbbDecodeMap };
static CmscbbAsn1Functions g_cvbAsnFuncBitsToInt = { CmscbbBitsToInt };
static CmscbbAsn1Functions g_cvbAsnFuncExku = { CmscbbOidToExku };
#endif

/* defined CmscbbAsnOcts decode template */
static CmscbbAsn1Item g_itemCmscbbAsnOcts = {
    CVB_NULL, &g_cvbAsnFuncOct, CMSCBB_RELOC_INIT_VAL CBC_ANY_CLASS,
    CBF_ANY_FORM, CBT_ANY_CODE, 0, sizeof(CmscbbAsnOcts)
};

/* defined CmscbbAsnBigint decode template */
static CmscbbAsn1Item g_itemCmscbbAsnBigint = {
    CVB_NULL, &g_cvbAsnFuncOct, CMSCBB_RELOC_INIT_VAL CBC_UNIV, CBF_PRIM,
    CBT_INTEGER, 0, sizeof(CmscbbAsnOcts)
};

/* defined CmscbbAsnSeq decode template */
static CmscbbAsn1Item g_itemCmscbbAsnSeq = {
    CVB_NULL, &g_cvbAsnFuncOct, CMSCBB_RELOC_INIT_VAL CBC_UNIV, CBF_CONS,
    CBT_SEQUENCES, 0, sizeof(CmscbbAsnOcts)
};

#if !CMSCBB_SUPPORT_SIGNED_ATTRIBUTE
/* defined CmscbbAsnSet decode template */
static CmscbbAsn1Item g_itemCmscbbAsnSet = {
    CVB_NULL, &g_cvbAsnFuncOct, CMSCBB_RELOC_INIT_VAL CBC_UNIV, CBF_CONS,
    CBT_SETS, 0, sizeof(CmscbbAsnOcts)
};
#endif

/* defined CmscbbAsnBits decode template */
static CmscbbAsn1Item g_itemCmscbbAsnBits = {
    CVB_NULL, &g_cvbAsnFuncBits, CMSCBB_RELOC_INIT_VAL CBC_UNIV, CBF_PRIM,
    CBT_BITSTRING, 0, sizeof(CmscbbAsnBits)
};

/* defined CmscbbAsnInt decode template */
static CmscbbAsn1Item g_itemCmscbbAsnInt = {
    CVB_NULL, &g_cvbAsnFuncInt, CMSCBB_RELOC_INIT_VAL CBC_UNIV, CBF_PRIM,
    CBT_INTEGER, 0, sizeof(CmscbbAsnInt)
};

/* defined CmscbbAsnEnum decode template */
static CmscbbAsn1Item g_itemCmscbbAsnEnum = {
    CVB_NULL, &g_cvbAsnFuncInt, CMSCBB_RELOC_INIT_VAL CBC_UNIV, CBF_PRIM,
    CBT_ENUM, 0, sizeof(CmscbbAsnEnum)
};

/* defined MSCBB_ASN_BOOL decode template */
static CmscbbAsn1Item g_itemCmscbbAsnBool = {
    CVB_NULL, &g_cvbAsnFuncInt, CMSCBB_RELOC_INIT_VAL CBC_UNIV, CBF_PRIM,
    CBT_BOOLEAN, 0, sizeof(CmscbbAsnBool)
};

#define MAX_OID_COUNT_IN_BUNDLE 10
/* template for CmscbbAsnOidBundle */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbAsnOidBundle) = {
    CMSCBB_ASN_SET_ITEM(CmscbbAsnOidBundle, CmscbbAsnOcts, oidBundle, (CVB_ULONG)MAX_OID_COUNT_IN_BUNDLE),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbAsnOidBundle, g_cvbAsnFuncSetOf, CBT_SEQUENCES);

/* template for X509 Certificate and CRL */
#if CMSCBB_SUPPORT_SIGNED_ATTRIBUTE
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509SignedAttrs) = {
    CMSCBB_ASN_MAP_ITEM(CmscbbX509SignedAttrs, CmscbbAsnOcts, contentType, AODI_PKCS9_AT_CONTENTTYPE),
    CMSCBB_ASN_MAP_ITEM(CmscbbX509SignedAttrs, CmscbbAsnOcts, hashValue, AOID_PKCS9_AT_MESSAGEDIGEST),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509SignedAttrs, g_cvbAsnFuncMap, CBT_SETS);
#endif

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509UnsignedAttrs) = {
    CMSCBB_ASN_MAP_FLAG_ITEM(CmscbbX509UnsignedAttrs, CmscbbAsnOcts, timestamp, CVB_ASN_RAW_DER,
        AOID_PKCS9_AT_TIMESTAMP_TOKEN),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509UnsignedAttrs, g_cvbAsnFuncMap, CBT_SETS);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509RevokeAttrs) = {
    CMSCBB_ASN_MAP_ITEM(CmscbbX509RevokeAttrs, CmscbbAsnEnum, reason, AOID_CE_CRLREASONS),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509RevokeAttrs, g_cvbAsnFuncMap, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509RevokeEntry) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509RevokeEntry, CmscbbAsnBigint, userCert),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509RevokeEntry, CmscbbAsnOcts, revocationDate),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbX509RevokeEntry, CmscbbX509RevokeAttrs, attrs),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509RevokeEntry, g_cvbAsnFuncSeq, CBT_SEQUENCES);

#define MAX_REVOKE_COUNT 20
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509Revoked) = {
    CMSCBB_ASN_SET_ITEM(CmscbbX509Revoked, CmscbbX509RevokeEntry, revokedList, (CVB_ULONG)MAX_REVOKE_COUNT),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509Revoked, g_cvbAsnFuncSetOf, CBT_SEQUENCES);

#if CMSCBB_SUPPORT_INDIRECT_CRL
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509IssuingDistPoint) = {
    CMSCBB_ASN_IMPLICIT_ITEM(CmscbbX509IssuingDistPoint, CmscbbAsnOcts, distpoint, 0),
    CMSCBB_ASN_NORMAL_IMP_ITEM(CmscbbX509IssuingDistPoint, CmscbbAsnBool, onlyuser, 1),
    CMSCBB_ASN_NORMAL_IMP_ITEM(CmscbbX509IssuingDistPoint, CmscbbAsnBool, onlyCA, 2), /* Offset tag : 2 */
    CMSCBB_ASN_IMPLICIT_ITEM(CmscbbX509IssuingDistPoint, CmscbbAsnBits, onlysomereasons, 3), /* Offset tag : 3 */
    CMSCBB_ASN_NORMAL_IMP_ITEM(CmscbbX509IssuingDistPoint, CmscbbAsnBool, indirectCRL, 4), /* Offset tag : 4 */
    CMSCBB_ASN_NORMAL_IMP_ITEM(CmscbbX509IssuingDistPoint, CmscbbAsnBool, onlyattr, 5), /* Offset tag : 5 */
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509IssuingDistPoint, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509CrlAttrs) = {
    CMSCBB_ASN_MAP_ITEM(CmscbbX509CrlAttrs, CmscbbX509IssuingDistPoint, idp, AOID_CE_ISSUINGDISTRIBUTIONPOINT),
    CMSCBB_ASN_MAP_ITEM(CmscbbX509CrlAttrs, CmscbbAsnInt, crlNumber, AOID_CE_CRLNUMBER),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509CrlAttrs, g_cvbAsnFuncMap, CBT_SEQUENCES);
#endif

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509AttrEntry) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509AttrEntry, CmscbbAsnOcts, id),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509AttrEntry, CmscbbAsnOcts, value),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509AttrEntry, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509AttrBundle) = {
    CMSCBB_ASN_SET_ITEM(CmscbbX509AttrBundle, CmscbbX509AttrEntry, attrs, (CVB_ULONG)CMSCBB_X509_ATTR_ENTRY_COUNT),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509AttrBundle, g_cvbAsnFuncSetOf, CBT_SETS);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509Name) = {
    CMSCBB_ASN_SET_ITEM(CmscbbX509Name, CmscbbX509AttrBundle, names, (CVB_ULONG)CMSCBB_X509_ATTR_COUNT),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509Name, g_cvbAsnFuncSetOf, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509AlgoIdentifier) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509AlgoIdentifier, CmscbbAsnOcts, algorithm),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbX509AlgoIdentifier, CmscbbAsnOcts, parameters),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509AlgoIdentifier, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509MaskGenAlgo) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509MaskGenAlgo, CmscbbAsnOcts, maskOid),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbX509MaskGenAlgo, CmscbbX509AlgoIdentifier, maskAlgo),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509MaskGenAlgo, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509PssParam) = {
    CMSCBB_ASN_EXPLICIT_ITEM(CmscbbX509PssParam, CmscbbX509AlgoIdentifier, hashAlgorithm, CVB_ASN_IMPLICIT, 0),
    CMSCBB_ASN_EXPLICIT_ITEM(CmscbbX509PssParam, CmscbbX509MaskGenAlgo, maskGenAlgorithm, CVB_ASN_IMPLICIT, 1),
    CMSCBB_ASN_EXPLICIT_ITEM(CmscbbX509PssParam, CmscbbAsnInt, saltLength, CVB_ASN_EXPLICIT, 2), /* Offset tag : 2 */
    CMSCBB_ASN_EXPLICIT_ITEM(CmscbbX509PssParam, CmscbbAsnInt, trailerField, CVB_ASN_OPTIONAL, 3), /* Offset tag : 3 */
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509PssParam, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509AlgoPssIdentifier) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509AlgoPssIdentifier, CmscbbAsnOcts, algorithm),
    CMSCBB_ASN_PEEK_OPTIONAL_ITEM(CmscbbX509AlgoPssIdentifier, rawSigned),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbX509AlgoPssIdentifier, CmscbbX509PssParam, pssPara),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbX509AlgoPssIdentifier, CmscbbAsnOcts, para),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509AlgoPssIdentifier, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509CrlInfo) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CrlInfo, CmscbbAsnInt, version),
    CMSCBB_ASN_IGNORE_NORMAL_ITEM(CmscbbX509CrlInfo, CmscbbAsnSeq),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CrlInfo, CmscbbX509Name, issuer),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CrlInfo, CmscbbAsnOcts, thisUpdateTime),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CrlInfo, CmscbbAsnOcts, nextUpdateTime),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbX509CrlInfo, CmscbbX509Revoked, revokedCerts),
#if CMSCBB_SUPPORT_INDIRECT_CRL
    CMSCBB_ASN_EXPLICIT_ITEM(CmscbbX509CrlInfo, CmscbbX509CrlAttrs, extensions, CVB_ASN_OPTIONAL, 0),
#else
    CMSCBB_ASN_IGNORE_EX_ITEM(CmscbbX509CrlInfo, CmscbbAsnSeq, CVB_ASN_OPTIONAL, CVB_ASN_EXPLICIT, 0),
#endif
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509CrlInfo, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbEccSign) = {
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbEccSign, CmscbbAsnBigint, xValue),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbEccSign, CmscbbAsnBigint, yValue),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbEccSign, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509Crl) = {
    CMSCBB_ASN_PEEK_ITEM(CmscbbX509Crl, rawSigned),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509Crl, CmscbbX509CrlInfo, tbsCertList),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509Crl, CmscbbX509AlgoPssIdentifier, algorithm),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509Crl, CmscbbAsnBits, signature),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509Crl, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509ExtensionEntry) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509ExtensionEntry, CmscbbAsnOcts, extnId),
    CMSCBB_ASN_DEFAULT_ITEM(CmscbbX509ExtensionEntry, CmscbbAsnBool, critical, 0),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509ExtensionEntry, CmscbbAsnOcts, extnValue),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509ExtensionEntry, g_cvbAsnFuncSeq, CBT_SEQUENCES);

/* template for CmscbbPkcs7IssuerAndSerial */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbPkcs7IssuerAndSerial) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7IssuerAndSerial, CmscbbX509Name, issuer),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7IssuerAndSerial, CmscbbAsnBigint, sn),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbPkcs7IssuerAndSerial, g_cvbAsnFuncSeq, CBT_SEQUENCES);

/* template for CmscbbTsMsgImprint */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbTsMsgImprint) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbTsMsgImprint, CmscbbX509AlgoIdentifier, hashAlgo),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbTsMsgImprint, CmscbbAsnOcts, hashValue),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbTsMsgImprint, g_cvbAsnFuncSeq, CBT_SEQUENCES);

/* template for CmscbbTimestampInfo */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbTimestampInfo) = {
    CMSCBB_ASN_IGNORE_NORMAL_ITEM(CmscbbTimestampInfo, CmscbbAsnInt),
    CMSCBB_ASN_IGNORE_NORMAL_ITEM(CmscbbTimestampInfo, CmscbbAsnOcts),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbTimestampInfo, CmscbbTsMsgImprint, msgImprint),
    CMSCBB_ASN_IGNORE_NORMAL_ITEM(CmscbbTimestampInfo, CmscbbAsnBigint),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbTimestampInfo, CmscbbAsnOcts, time),
    CMSCBB_ASN_IGNORE_ITEM(CmscbbTimestampInfo, CmscbbAsnSeq, CVB_ASN_OPTIONAL), /* accuracy */
    CMSCBB_ASN_IGNORE_ITEM(CmscbbTimestampInfo, CmscbbAsnBool, CVB_ASN_OPTIONAL), /* ordering */
    CMSCBB_ASN_IGNORE_ITEM(CmscbbTimestampInfo, CmscbbAsnBigint, CVB_ASN_OPTIONAL), /* nonce */
    /* issuer */
    CMSCBB_ASN_IGNORE_EX_ITEM(CmscbbTimestampInfo, CmscbbAsnSeq, CVB_ASN_OPTIONAL, CVB_ASN_IMPLICIT, 0),
    /* extensions */
    CMSCBB_ASN_IGNORE_EX_ITEM(CmscbbTimestampInfo, CmscbbAsnSeq, CVB_ASN_OPTIONAL, CVB_ASN_IMPLICIT, 1),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbTimestampInfo, g_cvbAsnFuncSeq, CBT_SEQUENCES);


#if CMSCBB_SUPPORT_SIGNED_ATTRIBUTE
CVB_STATIC CmscbbAsn1Item g_itemCmscbbAttrBundleRaw = { CVB_NULL, &g_cvbAsnFuncOct, CMSCBB_RELOC_INIT_VAL CBC_UNIV,
    CBF_CONS, CBT_SETS, 0, sizeof(CmscbbAsnOcts) };
#endif

/* template for CmscbbPkcs7SignedInfo */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbPkcs7SignedInfo) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7SignedInfo, CmscbbAsnInt, version),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7SignedInfo, CmscbbPkcs7IssuerAndSerial, issuerSn),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7SignedInfo, CmscbbX509AlgoIdentifier, digestAlgo),
#if CMSCBB_SUPPORT_SIGNED_ATTRIBUTE
    CMSCBB_ASN_IMPLICIT_PEEK_ITEM(CmscbbPkcs7SignedInfo, CmscbbAttrBundleRaw, rawSigned, 0),
    CMSCBB_ASN_IMPLICIT_ITEM(CmscbbPkcs7SignedInfo, CmscbbX509SignedAttrs, authAttrs, 0),
#else
    CMSCBB_ASN_IGNORE_ITEM(CmscbbPkcs7SignedInfo, CmscbbAsnSet, CVB_ASN_OPTIONAL),
#endif
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7SignedInfo, CmscbbX509AlgoPssIdentifier, signatureAlgo),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7SignedInfo, CmscbbAsnOcts, encryptedDigest),
    CMSCBB_ASN_IMPLICIT_ITEM(CmscbbPkcs7SignedInfo, CmscbbX509UnsignedAttrs, unauthAttrs, 1),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbPkcs7SignedInfo, g_cvbAsnFuncSeq, CBT_SEQUENCES);

#define MAX_SIGNED_DATA_COUNT 5
/* template for CmscbbPkcs7SignedData */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509CertRawBundle) = {
    CMSCBB_ASN_SET_ITEM_WITH_FLAG(CmscbbX509CertRawBundle, CVB_ASN_RAW_DER, CmscbbAsnOcts, bundle,
        (CVB_ULONG)MAX_SIGNED_DATA_COUNT),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509CertRawBundle, g_cvbAsnFuncSetOf, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509CrlRawBundle) = {
    CMSCBB_ASN_SET_ITEM_WITH_FLAG(CmscbbX509CrlRawBundle, CVB_ASN_RAW_DER, CmscbbAsnOcts, bundle,
        (CVB_ULONG)MAX_SIGNED_DATA_COUNT),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509CrlRawBundle, g_cvbAsnFuncSetOf, CBT_SEQUENCES);

/* template for CmscbbPkcs7DigestAlgoBundle */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbPkcs7DigestAlgoBundle) = {
    CMSCBB_ASN_SET_ITEM(CmscbbPkcs7DigestAlgoBundle, CmscbbX509AlgoIdentifier, digests, (CVB_VOID*)(CVB_ULONG)1),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbPkcs7DigestAlgoBundle, g_cvbAsnFuncSetOf, CBT_SETS);

/* template for CmscbbPkcs7ContentInfo */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbPkcs7ContentInfo) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7ContentInfo, CmscbbAsnOcts, type),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbPkcs7ContentInfo, CmscbbAsnOcts, content),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbPkcs7ContentInfo, g_cvbAsnFuncSeq, CBT_SEQUENCES);

/* template for CmscbbPkcs7SignedInfoBundle */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbPkcs7SignedInfoBundle) = {
    CMSCBB_ASN_SET_ITEM(CmscbbPkcs7SignedInfoBundle, CmscbbPkcs7SignedInfo, infos, (CVB_VOID*)(CVB_ULONG)1),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbPkcs7SignedInfoBundle, g_cvbAsnFuncSetOf, CBT_SETS);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbPkcs7SignedData) = {
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbPkcs7SignedData, CmscbbAsnInt, version),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7SignedData, CmscbbPkcs7DigestAlgoBundle, digestAlgos),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7SignedData, CmscbbPkcs7ContentInfo, content),
    CMSCBB_ASN_IMPLICIT_ITEM(CmscbbPkcs7SignedData, CmscbbX509CertRawBundle, rawCerts, 0),
    /* crl */
    CMSCBB_ASN_IMPLICIT_ITEM(CmscbbPkcs7SignedData, CmscbbX509CrlRawBundle, rawCrls, 1),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7SignedData, CmscbbPkcs7SignedInfoBundle, signerInfos),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbPkcs7SignedData, g_cvbAsnFuncSeq, CBT_SEQUENCES);

/* template for CmscbbPkcs7Content */
CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbPkcs7Content) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbPkcs7Content, CmscbbAsnOcts, contentType),
    CMSCBB_ASN_EXPLICIT_ITEM(CmscbbPkcs7Content, CmscbbPkcs7SignedData, signedData, CVB_ASN_NORMAL, 0),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbPkcs7Content, g_cvbAsnFuncSeq, CBT_SEQUENCES);


#if CMSCBB_RELOC_STRICT_CHECK
CVB_STATIC CmscbbAsn1Item g_itemCmscbbAsnBitsToInt = {
    CVB_NULL, &g_cvbAsnFuncBitsToInt, CVB_FALSE, CBC_UNIV,
    CBF_PRIM, CBT_BITSTRING, 0, sizeof(CmscbbAsnInt)
};
CVB_STATIC CmscbbAsn1Item g_itemCmscbbAsnExku = {
    CVB_NULL, &g_cvbAsnFuncExku, CVB_FALSE, CBC_UNIV, CBF_PRIM,
    CBT_OID, 0, sizeof(CmscbbAsnInt)
};
#else
CVB_STATIC CmscbbAsn1Item g_itemCmscbbAsnBitsToInt = {
    CVB_NULL, &g_cvbAsnFuncBitsToInt, CBC_UNIV, CBF_PRIM,
    CBT_BITSTRING, 0, sizeof(CmscbbAsnInt)
};
CVB_STATIC CmscbbAsn1Item g_itemCmscbbAsnExku = {
    CVB_NULL, &g_cvbAsnFuncExku, CBC_UNIV, CBF_PRIM, CBT_OID, 0, sizeof(CmscbbAsnInt)
};
#endif

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509BasicConstraints) = {
    CMSCBB_ASN_DEFAULT_ITEM(CmscbbX509BasicConstraints, CmscbbAsnBool, isCa, CVB_FALSE),
    CMSCBB_ASN_IGNORE_ITEM(CmscbbX509BasicConstraints, CmscbbAsnOcts, CVB_ASN_OPTIONAL),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509BasicConstraints, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509CertExts) = {
    CMSCBB_ASN_MAP_ITEM(CmscbbX509CertExts, CmscbbX509BasicConstraints, caInfo, AOID_CE_BASICCONSTRAINTS),
    CMSCBB_ASN_MAP_ITEM(CmscbbX509CertExts, CmscbbAsnBitsToInt, ku, AOID_CE_KEYUSAGE),
    CMSCBB_ASN_MAP_ITEM(CmscbbX509CertExts, CmscbbAsnExku, exku, AOID_CE_EXTKEYUSAGE),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509CertExts, g_cvbAsnFuncMap, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509Validity) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509Validity, CmscbbAsnOcts, notBefore),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509Validity, CmscbbAsnOcts, notAfter),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509Validity, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbRsaPublicKey) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbRsaPublicKey, CmscbbAsnBigint, modules),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbRsaPublicKey, CmscbbAsnBigint, publicExponent),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbRsaPublicKey, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509PublicKey) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509PublicKey, CmscbbRsaPublicKey, rsaPubKey),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509PublicKey, g_cvbAsnFuncSeq, CBT_BITSTRING);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509PubkeyInfo) = {
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509PubkeyInfo, CmscbbX509AlgoPssIdentifier, algorithm),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbX509PubkeyInfo, CmscbbX509PublicKey, subjectPublicKey),
    CMSCBB_ASN_OPTIONAL_ITEM(CmscbbX509PubkeyInfo, CmscbbAsnBits, eccPubKey),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509PubkeyInfo, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509CertInfo) = {
    CMSCBB_ASN_IGNORE_EX_ITEM(CmscbbX509CertInfo, CmscbbAsnInt, CVB_ASN_IGNORE, CVB_ASN_EXPLICIT, 0),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CertInfo, CmscbbAsnBigint, serialNumber),
    CMSCBB_ASN_IGNORE_NORMAL_ITEM(CmscbbX509CertInfo, CmscbbAsnSeq),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CertInfo, CmscbbX509Name, issuer),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CertInfo, CmscbbX509Validity, validity),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CertInfo, CmscbbX509Name, subject),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509CertInfo, CmscbbX509PubkeyInfo, subjectPubKey),
    /* issuerUID */
    CMSCBB_ASN_IGNORE_EX_ITEM(CmscbbX509CertInfo, CmscbbAsnBits, CVB_ASN_OPTIONAL, CVB_ASN_IMPLICIT, 1),
    /* subjectUID */
    CMSCBB_ASN_IGNORE_EX_ITEM(CmscbbX509CertInfo, CmscbbAsnBits, CVB_ASN_OPTIONAL, CVB_ASN_IMPLICIT, 2), /* 2 is tag */
    /* extensions */
    CMSCBB_ASN_EXPLICIT_ITEM(CmscbbX509CertInfo, CmscbbX509CertExts, extensions, CVB_ASN_OPTIONAL, 3), /* 3 is a tag */
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509CertInfo, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CMSCBB_ASN_TEMPLATE_BEGIN(CmscbbX509Cert) = {
    CMSCBB_ASN_PEEK_ITEM(CmscbbX509Cert, rawSigned),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509Cert, CmscbbX509CertInfo, toBeSigned),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509Cert, CmscbbX509AlgoPssIdentifier, algorithm),
    CMSCBB_ASN_NORMAL_ITEM(CmscbbX509Cert, CmscbbAsnBits, signature),
};
CMSCBB_ASN_TEMPLATE_END_STATIC(CmscbbX509Cert, g_cvbAsnFuncSeq, CBT_SEQUENCES);

CmscbbAsn1Item *CmscbbGetCmscbbX509BasicConstraints(void)
{
    return &g_itemCmscbbX509BasicConstraints;
}

CmscbbAsn1Item *CmscbbGetCmscbbX509Cert(void)
{
    return &g_itemCmscbbX509Cert;
}

CmscbbAsn1Item *CmscbbGetCmscbbPkcs7Content(void)
{
    return &g_itemCmscbbPkcs7Content;
}

CmscbbAsn1Item *CmscbbGetCmscbbX509Crl(void)
{
    return &g_itemCmscbbX509Crl;
}

#if CMSCBB_SUPPORT_INDIRECT_CRL
CmscbbAsn1Item *CmscbbGetX509IssuingDistPoint(void)
{
    return &g_itemCmscbbX509IssuingDistPoint;
}

#endif

CmscbbAsn1Item *CmscbbGetCmscbbTimestampInfo(void)
{
    return &g_itemCmscbbTimestampInfo;
}

CmscbbAsn1Item *CmscbbGetCmscbbAsnOcts(void)
{
    return &g_itemCmscbbAsnOcts;
}

CmscbbAsn1Item *CmscbbGetCmscbbAsnEnum(void)
{
    return &g_itemCmscbbAsnEnum;
}

CmscbbAsn1Item *CmscbbGetCmscbbAsnBits(void)
{
    return &g_itemCmscbbAsnBits;
}

CmscbbAsn1Item *CmscbbGetCmscbbX509ExtensionEntry(void)
{
    return &g_itemCmscbbX509ExtensionEntry;
}

CmscbbAsn1Item *CmscbbGetCmscbbAsnOidBundle(void)
{
    return &g_itemCmscbbAsnOidBundle;
}

CmscbbAsn1Item *CmscbbGetCmscbbEccSign(void)
{
    return &g_itemCmscbbEccSign;
}

#if CMSCBB_DELAY_ADDRESS_SET
CVB_VOID CmscbbAsn1TemplInit(CVB_VOID)
{
    g_templCmscbbAsnOidBundle[0].asn1Item = &g_itemCmscbbAsnOcts;
    return;
}

CVB_VOID CmscbbCmsTemplInit(CVB_VOID)
{
    int i;
    /* CmscbbPkcs7IssuerAndSerial */
    g_templCmscbbPkcs7IssuerAndSerial[0].asn1Item = &g_itemCmscbbX509Name;
    g_templCmscbbPkcs7IssuerAndSerial[1].asn1Item = &g_itemCmscbbAsnBigint;

    /* CmscbbX509SignedAttrs */
    g_templCmscbbX509SignedAttrs[0].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509SignedAttrs[1].asn1Item = &g_itemCmscbbAsnOcts;

    /* CmscbbX509UnsignedAttrs */
    g_templCmscbbX509UnsignedAttrs[0].asn1Item = &g_itemCmscbbAsnOcts;

    /* CmscbbPkcs7SignedInfo */
    i = 0;
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbAsnInt;
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbPkcs7IssuerAndSerial;
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbX509AlgoIdentifier;
#if CMSCBB_SUPPORT_SIGNED_ATTRIBUTE
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbAttrBundleRaw;
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbX509SignedAttrs;
#else
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbAsnSet;
#endif
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbX509AlgoPssIdentifier;
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbPkcs7SignedInfo[i++].asn1Item = &g_itemCmscbbX509UnsignedAttrs;

    /* CmscbbPkcs7SignedInfoBundle */
    g_templCmscbbPkcs7SignedInfoBundle[0].asn1Item = &g_itemCmscbbPkcs7SignedInfo;

    /* CmscbbPkcs7DigestAlgoBundle */
    g_templCmscbbPkcs7DigestAlgoBundle[0].asn1Item = &g_itemCmscbbX509AlgoIdentifier;

    /* CmscbbPkcs7ContentInfo */
    g_templCmscbbPkcs7ContentInfo[0].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbPkcs7ContentInfo[1].asn1Item = &g_itemCmscbbAsnOcts;

    /* CmscbbX509CertRawBundle */
    g_templCmscbbX509CertRawBundle[0].asn1Item = &g_itemCmscbbAsnOcts;
    /* CmscbbX509CrlRawBundle */
    g_templCmscbbX509CrlRawBundle[0].asn1Item = &g_itemCmscbbAsnOcts;

    /* CMSCBB_PKCS7_SIGNED_DATA */
    i = 0;
    g_templCmscbbPkcs7SignedData[i++].asn1Item = &g_itemCmscbbAsnInt;
    g_templCmscbbPkcs7SignedData[i++].asn1Item = &g_itemCmscbbPkcs7DigestAlgoBundle;
    g_templCmscbbPkcs7SignedData[i++].asn1Item = &g_itemCmscbbPkcs7ContentInfo;
    g_templCmscbbPkcs7SignedData[i++].asn1Item = &g_itemCmscbbX509CertRawBundle;
    g_templCmscbbPkcs7SignedData[i++].asn1Item = &g_itemCmscbbX509CrlRawBundle;
    g_templCmscbbPkcs7SignedData[i++].asn1Item = &g_itemCmscbbPkcs7SignedInfoBundle;

    /* CmscbbPkcs7Content */
    g_templCmscbbPkcs7Content[0].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbPkcs7Content[1].asn1Item = &g_itemCmscbbPkcs7SignedData;

    /* CmscbbTsMsgImprint */
    g_templCmscbbTsMsgImprint[0].asn1Item = &g_itemCmscbbX509AlgoIdentifier;
    g_templCmscbbTsMsgImprint[1].asn1Item = &g_itemCmscbbAsnOcts;

    /* CMSCBB_TST_INFO */
    i = 0;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnInt;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbTsMsgImprint;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnBigint;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnSeq;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnBool;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnBigint;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnSeq;
    g_templCmscbbTimestampInfo[i++].asn1Item = &g_itemCmscbbAsnSeq;
}

CVB_STATIC CVB_VOID InternalCmscbbX509TemplInit1(CVB_VOID)
{
    /* CmscbbX509AlgoIdentifier */
    g_templCmscbbX509AlgoIdentifier[0].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509AlgoIdentifier[1].asn1Item = &g_itemCmscbbAsnOcts;

    /* CmscbbX509MaskGenAlgo */
    g_templCmscbbX509MaskGenAlgo[0].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509MaskGenAlgo[1].asn1Item = &g_itemCmscbbX509AlgoIdentifier;

    int i = 0;
    /* CmscbbX509Param */
    g_templCmscbbX509PssParam[i++].asn1Item = &g_itemCmscbbX509AlgoIdentifier;
    g_templCmscbbX509PssParam[i++].asn1Item = &g_itemCmscbbX509MaskGenAlgo;
    g_templCmscbbX509PssParam[i++].asn1Item = &g_itemCmscbbAsnInt;
    g_templCmscbbX509PssParam[i++].asn1Item = &g_itemCmscbbAsnInt;

    /* CmscbbX509AlgoPssIdentifier */
    i = 0;
    g_templCmscbbX509AlgoPssIdentifier[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509AlgoPssIdentifier[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509AlgoPssIdentifier[i++].asn1Item = &g_itemCmscbbX509PssParam;
    g_templCmscbbX509AlgoPssIdentifier[i++].asn1Item = &g_itemCmscbbAsnOcts;

    /* CmscbbX509AttrEntry */
    g_templCmscbbX509AttrEntry[0].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509AttrEntry[1].asn1Item = &g_itemCmscbbAsnOcts;

    /* CmscbbX509AttrBundle */
    g_templCmscbbX509AttrBundle[0].asn1Item = &g_itemCmscbbX509AttrEntry;

    /* CmscbbX509Name */
    g_templCmscbbX509Name[0].asn1Item = &g_itemCmscbbX509AttrBundle;

    /* CmscbbX509Validity */
    g_templCmscbbX509Validity[0].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509Validity[1].asn1Item = &g_itemCmscbbAsnOcts;

    /* CmscbbRsaPublicKey */
    g_templCmscbbRsaPublicKey[0].asn1Item = &g_itemCmscbbAsnBigint;
    g_templCmscbbRsaPublicKey[1].asn1Item = &g_itemCmscbbAsnBigint;

    /* CmscbbX509PublicKey */
    g_templCmscbbX509PublicKey[0].asn1Item = &g_itemCmscbbRsaPublicKey;

    /* CmscbbX509PubkeyInfo */
    i = 0;
    g_templCmscbbX509PubkeyInfo[i++].asn1Item = &g_itemCmscbbX509AlgoPssIdentifier;
    g_templCmscbbX509PubkeyInfo[i++].asn1Item = &g_itemCmscbbX509PublicKey;
    g_templCmscbbX509PubkeyInfo[i++].asn1Item = &g_itemCmscbbAsnBits;

    /* CmscbbEccSign */
    g_templCmscbbEccSign[0].asn1Item = &g_itemCmscbbAsnBigint;
    g_templCmscbbEccSign[1].asn1Item = &g_itemCmscbbAsnBigint;
}

CVB_STATIC CVB_VOID InternalCmscbbX509TemplInit2(CVB_VOID)
{
    int i = 0;
    /* CmscbbX509ExtensionEntry */
    g_templCmscbbX509ExtensionEntry[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509ExtensionEntry[i++].asn1Item = &g_itemCmscbbAsnBool;
    g_templCmscbbX509ExtensionEntry[i++].asn1Item = &g_itemCmscbbAsnOcts;

    /* CmscbbX509BasicConstraints */
    g_templCmscbbX509BasicConstraints[0].asn1Item = &g_itemCmscbbAsnBool;
    g_templCmscbbX509BasicConstraints[1].asn1Item = &g_itemCmscbbAsnOcts;

    i = 0;
    /* CmscbbX509CertExts */
    g_templCmscbbX509CertExts[i++].asn1Item = &g_itemCmscbbX509BasicConstraints;
    g_templCmscbbX509CertExts[i++].asn1Item = &g_itemCmscbbAsnBitsToInt;
    g_templCmscbbX509CertExts[i++].asn1Item = &g_itemCmscbbAsnExku;

    i = 0;
    /* CmscbbX509CertInfo */
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbAsnInt;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbAsnBigint;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbAsnSeq;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbX509Name;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbX509Validity;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbX509Name;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbX509PubkeyInfo;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbAsnBits;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbAsnBits;
    g_templCmscbbX509CertInfo[i++].asn1Item = &g_itemCmscbbX509CertExts;

    i = 0;
    /* CMSCBB_X509_CERT */
    g_templCmscbbX509Cert[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509Cert[i++].asn1Item = &g_itemCmscbbX509CertInfo;
    g_templCmscbbX509Cert[i++].asn1Item = &g_itemCmscbbX509AlgoPssIdentifier;
    g_templCmscbbX509Cert[i++].asn1Item = &g_itemCmscbbAsnBits;
}

CVB_STATIC CVB_VOID InternalCmscbbX509TemplInit3(CVB_VOID)
{
    int i = 0;
    /* CmscbbX509RevokeAttrs */
    g_templCmscbbX509RevokeAttrs[0].asn1Item = &g_itemCmscbbAsnEnum;

    /* CmscbbX509RevokeEntry */
    g_templCmscbbX509RevokeEntry[i++].asn1Item = &g_itemCmscbbAsnBigint;
    g_templCmscbbX509RevokeEntry[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509RevokeEntry[i++].asn1Item = &g_itemCmscbbX509RevokeAttrs;

    /* CmscbbX509Revoked */
    g_templCmscbbX509Revoked[0].asn1Item = &g_itemCmscbbX509RevokeEntry;

#if CMSCBB_SUPPORT_INDIRECT_CRL
    i = 0;
    /* CmscbbX509IssuingDistPoint */
    g_templCmscbbX509IssuingDistPoint[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509IssuingDistPoint[i++].asn1Item = &g_itemCmscbbAsnBool;
    g_templCmscbbX509IssuingDistPoint[i++].asn1Item = &g_itemCmscbbAsnBool;
    g_templCmscbbX509IssuingDistPoint[i++].asn1Item = &g_itemCmscbbAsnBits;
    g_templCmscbbX509IssuingDistPoint[i++].asn1Item = &g_itemCmscbbAsnBool;
    g_templCmscbbX509IssuingDistPoint[i++].asn1Item = &g_itemCmscbbAsnBool;

    /* CmscbbX509CrlAttrs */
    g_templCmscbbX509CrlAttrs[0].asn1Item = &g_itemCmscbbX509IssuingDistPoint;
    g_templCmscbbX509CrlAttrs[1].asn1Item = &g_itemCmscbbAsnInt;
#endif
    i = 0;
    /* CmscbbX509CrlInfo */
    g_templCmscbbX509CrlInfo[i++].asn1Item = &g_itemCmscbbAsnInt;
    g_templCmscbbX509CrlInfo[i++].asn1Item = &g_itemCmscbbAsnSeq;
    g_templCmscbbX509CrlInfo[i++].asn1Item = &g_itemCmscbbX509Name;
    g_templCmscbbX509CrlInfo[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509CrlInfo[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509CrlInfo[i++].asn1Item = &g_itemCmscbbX509Revoked;
#if CMSCBB_SUPPORT_INDIRECT_CRL
    g_templCmscbbX509CrlInfo[i++].asn1Item = &g_itemCmscbbX509CrlAttrs;
#else
    g_templCmscbbX509CrlInfo[i++].asn1Item = &g_itemCmscbbAsnSeq;
#endif

    i = 0;
    /* CmscbbX509Crl */
    g_templCmscbbX509Crl[i++].asn1Item = &g_itemCmscbbAsnOcts;
    g_templCmscbbX509Crl[i++].asn1Item = &g_itemCmscbbX509CrlInfo;
    g_templCmscbbX509Crl[i++].asn1Item = &g_itemCmscbbX509AlgoPssIdentifier;
    g_templCmscbbX509Crl[i++].asn1Item = &g_itemCmscbbAsnBits;
}

CVB_VOID CmscbbX509TemplInit(CVB_VOID)
{
    InternalCmscbbX509TemplInit1();
    InternalCmscbbX509TemplInit2();
    InternalCmscbbX509TemplInit3();
}
#endif
